<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #canvas {
        border: 1px solid;
      }
    </style>
  </head>

  <body>
    <canvas width="400" height="400" id="canvas"> 请升级你的服务器 </canvas>
    <script>
      var canvas = document.querySelector("#canvas");
      var context = canvas.getContext("2d");
      function Ball(x, y, r, color, dx, dy, dr, opcity) {
        this.x = x;
        this.y = y;
        this.r = r;
        this.color = color;
        this.dx = dx;
        this.dy = dy;
        this.dr = dr;
        this.opcity = opcity;
      }
      Ball.prototype.init = function () {
        if (this.r <= 0) return;
        context.beginPath();
        context.fillStyle = this.color;
        context.globalAlpha = this.opcity;
        context.arc(this.x + this.dx, this.y + this.dy, this.r + this.dr, 0, 7);
        context.fill();
      };
      var timer = 0;
      // function getBallList
      function getBallList(length = 20, speed = 0.5) {
        var list = [];
        for (let i = 0; i < length; i++) {
          let arr = [];
          let color = `rgb(${Math.floor(Math.random() * 255)},${Math.floor(
            Math.random() * 255
          )},${Math.floor(Math.random() * 255)})`;
          let x = Math.random() * 400;
          let y = Math.random() * 400;
          let r = Math.random() * 5 + 5;
          let signX = Math.random() > 0.5 ? 1 : -1;
          let signY = Math.random() > 0.5 ? 1 : -1;
          let dx = Math.floor((Math.random() * 1 + speed) * signX);
          let dy = Math.floor((Math.random() * 1 + speed) * signY);
          let opcity = Math.random();
          let dr = Math.random();
          arr.push(x);
          arr.push(y);
          arr.push(r);
          arr.push(color);
          arr.push(dx);
          arr.push(dy);
          arr.push(dr);
          arr.push(opcity);
          list.push(arr);
        }
        return list;
      }
      function getLineList(list, maxLength = 20) {
        var arr = [];
        for (let i = 0; i < list.length; i++) {
          for (let j = i + 1; j < list.length; j++) {
            var distance = Math.sqrt(
              Math.pow(list[i][0] - list[j][0], 2) +
                Math.pow(list[i][1] - list[j][1], 2)
            );
            if (distance < maxLength) {
              var tempArr = [];
              tempArr.push(list[i][0], list[i][1], list[j][0], list[j][1]);
              arr.push(tempArr);
            }
          }
        }
        return arr;
      }
      function drawLine(x1, y1, x2, y2) {
        context.beginPath();
        context.strokeStyle = "#000";
        context.globalAlpha=0.3;
        context.moveTo(x1, y1);
        context.lineTo(x2, y2);
        context.stroke();
      }
      function drawBalls(list) {
        list.forEach((item, index) => {
          var ball = new Ball(...item);
          ball.init();
        });
      }
      function drawLines(list) {
        var lineList = getLineList(list, 70);
        lineList.forEach((item) => {
          drawLine(...item);
        });
      }
      function ballRun() {
        var list = getBallList(50, 1);
        drawBalls(list);
        drawLines(list);
        animate(list);
      }
      function animate(list) {
        requestAnimationFrame(function () {
          list.map((item) => {
            item[0] += item[4];
            if (item[0] > 400 || item[0] < 0) {
              item[4] = item[4] * -1;
            }
            item[1] += item[5];
            if (item[1] > 400 || item[1] < 0) {
              item[5] = item[5] * -1;
            }
            return item;
          });
          context.clearRect(0, 0, 400, 400);
          drawBalls(list);
          drawLines(list);
          animate(list);
        });
      }
      window.onload = function () {
        ballRun();
      };
    </script>
  </body>
</html>
